using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using JGSY.CMS.LowCode.Platform.Application.DTOs.Common;
using JGSY.CMS.LowCode.Platform.Application.Extensions;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Domain.Entities;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 租户管理控制器
    /// 提供租户CRUD操作和管理功能
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    [Authorize] // 需要认证才能访问
    public class TenantsController : ControllerBase
    {
        private readonly ITenantService _tenantService;
        private readonly ILogger<TenantsController> _logger;

        public TenantsController(
            ITenantService tenantService,
            ILogger<TenantsController> logger)
        {
            _tenantService = tenantService;
            _logger = logger;
        }

        /// <summary>
        /// 获取租户列表
        /// </summary>
        /// <param name="request">查询请求参数</param>
        /// <returns>分页租户列表</returns>
        [HttpGet]
        [ProducesResponseType(typeof(PagedResult<TenantDto>), 200)]
        public async Task<ActionResult<PagedResult<TenantDto>>> GetTenants([FromQuery] GetTenantsRequest request)
        {
            try
            {
                var result = await _tenantService.GetTenantsAsync(request);
                
                var tenantDtos = result.Items.Select(t => new TenantDto
                {
                    TenantId = t.TenantId,
                    Name = t.Name,
                    DisplayName = t.DisplayName,
                    Description = t.Description,
                    SubDomain = t.SubDomain,
                    CustomDomain = t.CustomDomain,
                    Status = t.Status,
                    SubscriptionPlan = t.SubscriptionPlan,
                    ContactEmail = t.ContactEmail,
                    ContactPhone = t.ContactPhone,
                    TimeZone = t.TimeZone,
                    Language = t.Language,
                    LogoUrl = t.LogoUrl,
                    ExpiresAt = t.ExpiresAt,
                    LastActivityAt = t.LastActivityAt,
                    CreatedAt = t.CreatedAt,
                    UpdatedAt = t.UpdatedAt
                }).ToList();

                return Ok(new PagedResult<TenantDto>
                {
                    Items = tenantDtos,
                    TotalCount = result.TotalCount,
                    PageNumber = result.PageNumber,
                    PageSize = result.PageSize
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取租户列表失败");
                return StatusCode(500, new { message = "获取租户列表失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 根据ID获取租户信息
        /// </summary>
        /// <param name="tenantId">租户ID</param>
        /// <returns>租户信息</returns>
        [HttpGet("{tenantId}")]
        [ProducesResponseType(typeof(TenantDto), 200)]
        [ProducesResponseType(404)]
        public async Task<ActionResult<TenantDto>> GetTenant(string tenantId)
        {
            try
            {
                var tenant = await _tenantService.GetTenantByIdAsync(tenantId);
                
                if (tenant == null)
                {
                    return NotFound(new { message = $"租户不存在: {tenantId}" });
                }

                var tenantDto = new TenantDto
                {
                    TenantId = tenant.TenantId,
                    Name = tenant.Name,
                    DisplayName = tenant.DisplayName,
                    Description = tenant.Description,
                    SubDomain = tenant.SubDomain,
                    CustomDomain = tenant.CustomDomain,
                    Status = tenant.Status,
                    SubscriptionPlan = tenant.SubscriptionPlan,
                    ContactEmail = tenant.ContactEmail,
                    ContactPhone = tenant.ContactPhone,
                    TimeZone = tenant.TimeZone,
                    Language = tenant.Language,
                    LogoUrl = tenant.LogoUrl,
                    ExpiresAt = tenant.ExpiresAt,
                    LastActivityAt = tenant.LastActivityAt,
                    CreatedAt = tenant.CreatedAt,
                    UpdatedAt = tenant.UpdatedAt
                };

                return Ok(tenantDto);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取租户信息失败: {TenantId}", tenantId);
                return StatusCode(500, new { message = "获取租户信息失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 创建新租户
        /// </summary>
        /// <param name="request">创建租户请求</param>
        /// <returns>创建的租户信息</returns>
        [HttpPost]
        [ProducesResponseType(typeof(TenantDto), 201)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<TenantDto>> CreateTenant([FromBody] CreateTenantDto request)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                var tenant = await _tenantService.CreateTenantAsync(request.ToCreateRequest());
                
                var tenantDto = new TenantDto
                {
                    TenantId = tenant.TenantId,
                    Name = tenant.Name,
                    DisplayName = tenant.DisplayName,
                    Description = tenant.Description,
                    SubDomain = tenant.SubDomain,
                    CustomDomain = tenant.CustomDomain,
                    Status = tenant.Status,
                    SubscriptionPlan = tenant.SubscriptionPlan,
                    ContactEmail = tenant.ContactEmail,
                    ContactPhone = tenant.ContactPhone,
                    TimeZone = tenant.TimeZone,
                    Language = tenant.Language,
                    LogoUrl = tenant.LogoUrl,
                    ExpiresAt = tenant.ExpiresAt,
                    LastActivityAt = tenant.LastActivityAt,
                    CreatedAt = tenant.CreatedAt,
                    UpdatedAt = tenant.UpdatedAt
                };

                _logger.LogInformation("租户创建成功: {TenantId} - {Name}", tenant.TenantId, tenant.Name);
                
                return CreatedAtAction(nameof(GetTenant), new { tenantId = tenant.TenantId }, tenantDto);
            }
            catch (InvalidOperationException ex)
            {
                return BadRequest(new { message = ex.Message });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建租户失败: {Name}", request.Name);
                return StatusCode(500, new { message = "创建租户失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 更新租户信息
        /// </summary>
        /// <param name="tenantId">租户ID</param>
        /// <param name="request">更新请求</param>
        /// <returns>更新后的租户信息</returns>
        [HttpPut("{tenantId}")]
        [ProducesResponseType(typeof(TenantDto), 200)]
        [ProducesResponseType(404)]
        public async Task<ActionResult<TenantDto>> UpdateTenant(string tenantId, [FromBody] UpdateTenantDto request)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                var tenant = await _tenantService.UpdateTenantAsync(tenantId, request.ToUpdateRequest());
                
                var tenantDto = new TenantDto
                {
                    TenantId = tenant.TenantId,
                    Name = tenant.Name,
                    DisplayName = tenant.DisplayName,
                    Description = tenant.Description,
                    SubDomain = tenant.SubDomain,
                    CustomDomain = tenant.CustomDomain,
                    Status = tenant.Status,
                    SubscriptionPlan = tenant.SubscriptionPlan,
                    ContactEmail = tenant.ContactEmail,
                    ContactPhone = tenant.ContactPhone,
                    TimeZone = tenant.TimeZone,
                    Language = tenant.Language,
                    LogoUrl = tenant.LogoUrl,
                    ExpiresAt = tenant.ExpiresAt,
                    LastActivityAt = tenant.LastActivityAt,
                    CreatedAt = tenant.CreatedAt,
                    UpdatedAt = tenant.UpdatedAt
                };

                _logger.LogInformation("租户信息更新成功: {TenantId}", tenantId);
                
                return Ok(tenantDto);
            }
            catch (ArgumentException ex)
            {
                return NotFound(new { message = ex.Message });
            }
            catch (InvalidOperationException ex)
            {
                return BadRequest(new { message = ex.Message });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新租户信息失败: {TenantId}", tenantId);
                return StatusCode(500, new { message = "更新租户信息失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 删除租户（软删除）
        /// </summary>
        /// <param name="tenantId">租户ID</param>
        /// <returns>删除结果</returns>
        [HttpDelete("{tenantId}")]
        [ProducesResponseType(204)]
        [ProducesResponseType(404)]
        public async Task<ActionResult> DeleteTenant(string tenantId)
        {
            try
            {
                var result = await _tenantService.DeleteTenantAsync(tenantId);
                
                if (!result)
                {
                    return NotFound(new { message = $"租户不存在: {tenantId}" });
                }

                _logger.LogInformation("租户删除成功: {TenantId}", tenantId);
                
                return NoContent();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除租户失败: {TenantId}", tenantId);
                return StatusCode(500, new { message = "删除租户失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 激活租户
        /// </summary>
        /// <param name="tenantId">租户ID</param>
        /// <returns>操作结果</returns>
        [HttpPost("{tenantId}/activate")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        public async Task<ActionResult> ActivateTenant(string tenantId)
        {
            try
            {
                var result = await _tenantService.ActivateTenantAsync(tenantId);
                
                if (!result)
                {
                    return NotFound(new { message = $"租户不存在: {tenantId}" });
                }

                _logger.LogInformation("租户激活成功: {TenantId}", tenantId);
                
                return Ok(new { message = "租户激活成功" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "激活租户失败: {TenantId}", tenantId);
                return StatusCode(500, new { message = "激活租户失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 暂停租户
        /// </summary>
        /// <param name="tenantId">租户ID</param>
        /// <returns>操作结果</returns>
        [HttpPost("{tenantId}/suspend")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        public async Task<ActionResult> SuspendTenant(string tenantId)
        {
            try
            {
                var result = await _tenantService.SuspendTenantAsync(tenantId);
                
                if (!result)
                {
                    return NotFound(new { message = $"租户不存在: {tenantId}" });
                }

                _logger.LogInformation("租户暂停成功: {TenantId}", tenantId);
                
                return Ok(new { message = "租户暂停成功" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "暂停租户失败: {TenantId}", tenantId);
                return StatusCode(500, new { message = "暂停租户失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取租户资源使用情况
        /// </summary>
        /// <param name="tenantId">租户ID</param>
        /// <returns>资源使用情况</returns>
        [HttpGet("{tenantId}/resources")]
        [ProducesResponseType(typeof(List<TenantResourceUsage>), 200)]
        [ProducesResponseType(404)]
        public async Task<ActionResult<List<TenantResourceUsage>>> GetTenantResourceUsage(string tenantId)
        {
            try
            {
                var tenant = await _tenantService.GetTenantByIdAsync(tenantId);
                if (tenant == null)
                {
                    return NotFound(new { message = $"租户不存在: {tenantId}" });
                }

                var resourceUsages = new List<TenantResourceUsage>();
                
                // 获取各类资源使用情况
                var resourceTypes = new[] { "users", "storage", "api_calls" };
                
                foreach (var resourceType in resourceTypes)
                {
                    var usage = await _tenantService.GetTenantResourceUsageAsync(tenantId, resourceType);
                    resourceUsages.Add(new TenantResourceUsage
                    {
                        ResourceType = resourceType,
                        CurrentUsage = usage,
                        Unit = ResourceHelper.GetResourceUnit(resourceType)
                    });
                }

                return Ok(resourceUsages);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取租户资源使用情况失败: {TenantId}", tenantId);
                return StatusCode(500, new { message = "获取资源使用情况失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 验证租户有效性
        /// </summary>
        /// <param name="tenantId">租户ID</param>
        /// <returns>验证结果</returns>
        [HttpGet("{tenantId}/validate")]
        [ProducesResponseType(typeof(TenantValidationResult), 200)]
        public async Task<ActionResult<TenantValidationResult>> ValidateTenant(string tenantId)
        {
            try
            {
                var isValid = await _tenantService.ValidateTenantAsync(tenantId);
                var isActive = await _tenantService.IsTenantActiveAsync(tenantId);
                
                var result = new TenantValidationResult
                {
                    TenantId = tenantId,
                    IsValid = isValid,
                    IsActive = isActive,
                    ValidatedAt = DateTime.UtcNow
                };

                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "验证租户失败: {TenantId}", tenantId);
                return StatusCode(500, new { message = "验证租户失败", error = ex.Message });
            }
        }
    }

    /// <summary>
    /// 租户DTO
    /// </summary>
    public class TenantDto
    {
        public string TenantId { get; set; } = string.Empty;
        public string Name { get; set; } = string.Empty;
        public string? DisplayName { get; set; }
        public string? Description { get; set; }
        public string? SubDomain { get; set; }
        public string? CustomDomain { get; set; }
        public TenantStatus Status { get; set; }
        public string? SubscriptionPlan { get; set; }
        public string? ContactEmail { get; set; }
        public string? ContactPhone { get; set; }
        public string TimeZone { get; set; } = string.Empty;
        public string Language { get; set; } = string.Empty;
        public string? LogoUrl { get; set; }
        public DateTime? ExpiresAt { get; set; }
        public DateTime? LastActivityAt { get; set; }
        public DateTime CreatedAt { get; set; }
        public DateTime UpdatedAt { get; set; }
    }

    /// <summary>
    /// 租户验证结果DTO
    /// </summary>
    public class TenantValidationResult
    {
        public string TenantId { get; set; } = string.Empty;
        public bool IsValid { get; set; }
        public bool IsActive { get; set; }
        public DateTime ValidatedAt { get; set; }
    }
    
    /// <summary>
    /// 获取资源单位的辅助方法
    /// </summary>
    public static class ResourceHelper
    {
        public static string GetResourceUnit(string resourceType)
        {
            return resourceType switch
            {
                "users" => "个",
                "storage" => "MB", 
                "api_calls" => "次",
                _ => "个"
            };
        }
    }
}
